package com.blog.blogservice.api.controller.v1;

import com.blog.blogservice.app.service.UserService;
import com.blog.blogservice.config.JwtToken;
import com.blog.blogservice.domain.entity.BaseResponse;
import com.blog.blogservice.domain.entity.LoginEntity;
import com.blog.blogservice.util.JwtUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

@RestController
@RequestMapping("/v1")
public class LoginController {

    Logger logger = LoggerFactory.getLogger(LoginController.class);

    @Autowired
    private UserService userService;

    @PostMapping(value = "/login")
    public BaseResponse<String> userLogin(@RequestBody LoginEntity loginEntity, ServletResponse response) {


        // 获取当前用户主体
        Subject subject = SecurityUtils.getSubject();
        String msg = null;
        boolean loginSuccess = false;
        //密码加密
        String encryptPassword = JwtUtils.encryption(loginEntity.getPassword(), loginEntity.getUsername());
        System.out.println("密码咯：" + encryptPassword);
        //生成签名
        String token = JwtUtils.sign(loginEntity.getUsername(), encryptPassword);
        String refreshToken = JwtUtils.refreshTokenSign(loginEntity.getUsername(), encryptPassword);
        JwtToken jwtToken = new JwtToken(token);
        jwtToken.setPassword(encryptPassword);
        try {
            subject.login(jwtToken);
            msg = "登录成功。";
            loginSuccess = true;
        } catch (UnknownAccountException uae) { // 账号不存在
            msg = "用户名与密码不匹配，请检查后重新输入！";
        } catch (IncorrectCredentialsException ice) { // 账号与密码不匹配
            msg = "用户名与密码不匹配，请检查后重新输入！";
        } catch (LockedAccountException lae) { // 账号已被锁定
            msg = "该账户已被锁定，如需解锁请联系管理员！";
        } catch (AuthenticationException ae) { // 其他身份验证异常
            msg = "登录异常，请联系管理员！";
        }
        BaseResponse ret = new BaseResponse();
        if (loginSuccess) {
//            // 若登录成功，签发 JWT token
//            String jwtToken = JwtUtils.sign(loginEntity.getUsername(), JwtUtils.SECRET);
            // 将签发的 JWT token 设置到 HttpServletResponse 的 Header 中
            ((HttpServletResponse) response).setHeader(JwtUtils.AUTH_HEADER, token);
            ret.setCode("20000");
            ret.setMessage(msg);
            ret.setToken(token);
            ret.setRefreshToken(refreshToken);
//            logger.error("认证："+jwtToken);
            return ret;
        } else {
            ret.setCode("401");
            ret.setMessage(msg);
            return ret;
        }

    }

    @GetMapping("/logout")
    public Object logout() {
        BaseResponse ret = new BaseResponse();
        ret.setCode("0");
        ret.setMessage("退出登录");
        return ret;
    }

    @PostMapping("/token/refresh")
    public BaseResponse<String> refreshToken(@RequestBody String RefreshToken) {

        String userName = JwtUtils.getClaimFiled(RefreshToken, "username");
        // 查询数据库获取用户信息，此处使用 Map 来模拟数据库
        Boolean refreshTokenExpired = JwtUtils.refreshVerify(RefreshToken, userName, null);
        if (refreshTokenExpired) {
            BaseResponse ret = new BaseResponse();
            String token = JwtUtils.sign(userName, null);
            String refreshToken = JwtUtils.refreshTokenSign(userName, null);
            ret.setCode("20000");
            ret.setToken(token);
            ret.setRefreshToken(refreshToken);
            return ret;
        }
        return BaseResponse.error("验证错误");
    }

}
